package cn.dy.workatten.imp;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.dy.base.framework.esb.def.RepMessage;
import cn.dy.workatten.WorkAttenModuleImp;
import cn.dy.workatten.dao.AttendApplicationDao;
import cn.dy.workatten.dao.AttendRecordDao;
import cn.dy.workatten.dao.ContactInfoDao;
import cn.dy.workatten.dao.DutyScoreSummaryDao;
import cn.dy.workatten.dao.ScheduleCfgDao;
import cn.dy.workatten.pojo.AttendRecord;
import cn.dy.workatten.pojo.DutyScoreSummary;
import cn.dy.workatten.pojo.MemberInfo;
import cn.dy.workatten.pojo.ScheduleCfg;
import cn.dy.workatten.service.DutyAllowanceService;
import cn.dy.workatten.util.DateUtil;

public class DutyAllowanceServiceImpl implements DutyAllowanceService {

	protected static Logger logger = LoggerFactory.getLogger(DutyAllowanceServiceImpl.class);
	private DutyScoreSummaryDao dutyScoreSummaryDao;
	private ContactInfoDao contactInfoDao;
	private AttendRecordDao attendRecordDao;
	private ScheduleCfgDao scheduleCfgDao;
	private AttendApplicationDao attendApplicationDao;

	public DutyAllowanceServiceImpl() {
		this.dutyScoreSummaryDao = new DutyScoreSummaryDao();
		this.contactInfoDao = new ContactInfoDao();
		this.attendRecordDao = new AttendRecordDao();
		this.scheduleCfgDao = new ScheduleCfgDao();
		this.attendApplicationDao = new AttendApplicationDao();
	}

	@Override
	public RepMessage generateDutyAllowance(long dept_id2, String monthStr) {
		// 加值班补贴的手动生成（按月生成，某个部门所有的月份考勤情况）(根据考勤记录明细表生成 )
		RepMessage repMessage = new RepMessage();

		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
			SimpleDateFormat df2 = new SimpleDateFormat("yyyyMM");
			Date monthDate = df.parse(monthStr);
			long month = DateUtil.getDateMonth(monthDate);
			int year = DateUtil.getDateYear(monthDate);
			long yearMonth = Long.parseLong(df2.format(monthDate)); 

			// 判断这个月份的考勤是否已经存在
			List<DutyScoreSummary> list = this.dutyScoreSummaryDao.getDutyScoreSummaryList(0, yearMonth);
			if (list != null && list.size() > 0) {
				repMessage.setResponse_code("-1");
				repMessage.setResponse_desc("这个月份的考勤已经生成!");
				return repMessage;
			}

			// 判断要生成的月份是否可以生成，判断只能生成上个月份的考勤
			Date nowDate = new Date();
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(nowDate);
			calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
			String lastMonthStr = df.format(calendar.getTime());
			if (!monthStr.equalsIgnoreCase(lastMonthStr)) {
				repMessage.setResponse_code("-2");
				repMessage.setResponse_desc("只能生成上个月份的考勤!");
				return repMessage;
			}

			int user_id = Integer.parseInt(WorkAttenModuleImp.context.getContextByName("user_id").toString());
			// 这个月份的考勤审批是否有待审批的，本月的数据，下月来生成，同时若有未审批或审批不通过的考勤是不能生成的
			// 判断 bz_attend_application的attendance_month和sts==2代表审批申请完结
			// 这个月的考勤申请是否都已经审批通过
			int isExist = this.attendApplicationDao.isExistAttendAppNotEnd(yearMonth);
			if(isExist > 0) {
				repMessage.setResponse_code("-3");
				repMessage.setResponse_desc("存在未审批的考勤申请，无法生成本月考勤");
				return repMessage;
			}

			// 根据规则，生成加值班补贴的汇总记录，生成这个部门，这个月份的考勤
			// 查询所有的配置信息列表
			List<ScheduleCfg> scheduleCfgList = this.scheduleCfgDao.getAllScheduleCfg();
			HashMap<String, ScheduleCfg> scheduleCfgMap = new HashMap<String, ScheduleCfg>();
			for(ScheduleCfg oneScheduleCfg : scheduleCfgList) {
				scheduleCfgMap.put(String.valueOf(oneScheduleCfg.getId()), oneScheduleCfg);
			}
			
			// 获得所有的员工列表
			List<MemberInfo> memberInfoList = this.contactInfoDao.getMemberListByDept(0, null, 0, 0);
			
			// 加班费的计算，
			// 加值班费为：加班分值 X 月加班每分值补贴标准
			// 月加班每分值补贴标准=全体在岗民警总数X 710元 ÷全体民警月加班总分
			int allMemberCount = memberInfoList.size(); //  全体在岗民警总数
			double all_mem_overtime_score = 0; // 全体民警月加班总分
			double month_per_score = 0; // 月加班每分值补贴标准

			Date monthStartTime = DateUtil.getMonthStartTime(monthDate);
			Date monthEndTime = DateUtil.getMonthEndTime(monthDate);
			
			// 所有民警月考勤汇总列表
			List<DutyScoreSummary> allDutyScoreList = new ArrayList<DutyScoreSummary>();

			for (MemberInfo oneMemberInfo : memberInfoList) {
				DutyScoreSummary dutyScoreSummary = new DutyScoreSummary();

				long staff_id = oneMemberInfo.getId();
				long dept_id = oneMemberInfo.getDeptId();

				// 再根据bz_attend_record的staff_id和attend_day获得某个员工本月份的考勤信息列表
				List<AttendRecord> staffMonthRecordList = this.attendRecordDao.getAttendRecordsByStaffMon(staff_id,
						monthStartTime, monthEndTime);
				
				
				// 计算每一个员工考勤bz_attend_record的schedule_id关联的bz_schedule_cfg对应的是什么上班类型，进行计算值
				double schedule_1_score = 0,schedule_2_score = 0,schedule_3_score = 0,schedule_4_score = 0,schedule_5_score = 0,schedule_6_score = 0,
					schedule_7_score = 0,schedule_8_score = 0,schedule_9_score = 0,schedule_10_score = 0,schedule_11_score = 0,schedule_12_score = 0,
					schedule_13_score = 0,schedule_14_score = 0,schedule_15_score = 0;
				int schedule_1_day = 0,schedule_2_day = 0,schedule_3_day = 0,schedule_4_day = 0,schedule_5_day = 0,schedule_6_day = 0,
					schedule_7_day = 0,schedule_8_day = 0,schedule_9_day = 0,schedule_10_day = 0,schedule_11_day = 0,schedule_12_day = 0,
					schedule_13_day = 0,schedule_14_day = 0,schedule_15_day = 0,schedule_16_day = 0;
				double all_score = 0; // 总分值
				double overtime_score = 0; // 加班分值
				double overtime_pay = 0; // 加班费
				double schedule_16_score = 0;// 额外加班分值
				double midnight_score = 0; // 0点后加班分值
				
				for (AttendRecord oneRecord : staffMonthRecordList) {
					int oneScheduleId = (int) oneRecord.getSchedule_id();
					ScheduleCfg oneScheduleCfg = scheduleCfgMap.get(String.valueOf(oneScheduleId));
					double oneScore = oneScheduleCfg.getMan_hour() * Double.parseDouble(oneScheduleCfg.getRatio());
					all_score += oneScore; // 普通分值
					if(StringUtils.isNotEmpty(oneRecord.getWork_value())) { // 额外分值
						schedule_16_score += Double.parseDouble(oneRecord.getWork_value());
						all_score += schedule_16_score;
					}
					if(oneRecord.getMan_hour_midnight() > 0) { // 0点后加班分值
						midnight_score += oneRecord.getMan_hour_midnight();
						all_score += midnight_score;
					}
					
					switch (oneScheduleId) {
					case 1:
						schedule_1_score += oneScore;
						schedule_1_day ++;
						break;
					case 2:
						schedule_2_score += oneScore;
						schedule_2_day ++;
						break;
					case 3:
						schedule_3_score += oneScore;
						schedule_3_day ++;
						break;
					case 4:
						schedule_4_score += oneScore;
						schedule_4_day ++;
						break;
					case 5:
						schedule_5_score += oneScore;
						schedule_5_day ++;
						break;
					case 6:
						schedule_6_score += oneScore;
						schedule_6_day ++;
						break;
					case 7:
						schedule_7_score += oneScore;
						schedule_7_day ++;
						break;
					case 8:
						schedule_8_score += oneScore;
						schedule_8_day ++;
						break;
					case 9:
						schedule_9_score += oneScore;
						schedule_9_day ++;
						break;
					case 10:
						schedule_10_score += oneScore;
						schedule_10_day ++;
						break;
					case 11:
						schedule_11_score += oneScore;
						schedule_11_day ++;
						break;
					case 12:
						schedule_12_score += oneScore;
						schedule_12_day ++;
						break;
					case 13:
						schedule_13_score += oneScore;
						schedule_13_day ++;
						break;
					case 14:
						schedule_14_score += oneScore;
						schedule_14_day ++;
						break;
					case 15:
						schedule_15_score += oneScore;
						schedule_15_day ++;
						break;
					default:
						break;
					}

				}
				
				overtime_score = all_score - schedule_1_score;//  加班分值（总分值-法定分值）
				all_mem_overtime_score += overtime_score;
				
				dutyScoreSummary.setStaff_id(staff_id);
				dutyScoreSummary.setDept_id(dept_id);
				dutyScoreSummary.setMonth(yearMonth);
				dutyScoreSummary.setSchedule_1_score(String.valueOf((int)schedule_1_score));
				dutyScoreSummary.setSchedule_1_day(String.valueOf((int)schedule_1_day));
				dutyScoreSummary.setSchedule_2_score(String.valueOf((int)schedule_2_score));
				dutyScoreSummary.setSchedule_2_day(String.valueOf((int)schedule_2_day));
				dutyScoreSummary.setSchedule_3_score(String.valueOf((int)schedule_3_score));
				dutyScoreSummary.setSchedule_3_day(String.valueOf((int)schedule_3_day));
				dutyScoreSummary.setSchedule_4_score(String.valueOf((int)schedule_4_score));
				dutyScoreSummary.setSchedule_4_day(String.valueOf((int)schedule_4_day));
				dutyScoreSummary.setSchedule_5_score(String.valueOf((int)schedule_5_score));
				dutyScoreSummary.setSchedule_5_day(String.valueOf((int)schedule_5_day));
				dutyScoreSummary.setSchedule_6_score(String.valueOf((int)schedule_6_score));
				dutyScoreSummary.setSchedule_6_day(String.valueOf((int)schedule_6_day));
				dutyScoreSummary.setSchedule_7_score(String.valueOf((int)schedule_7_score));
				dutyScoreSummary.setSchedule_7_day(String.valueOf((int)schedule_7_day));
				dutyScoreSummary.setSchedule_8_score(String.valueOf((int)schedule_8_score));
				dutyScoreSummary.setSchedule_8_day(String.valueOf((int)schedule_8_day));
				dutyScoreSummary.setSchedule_9_score(String.valueOf((int)schedule_9_score));
				dutyScoreSummary.setSchedule_9_day(String.valueOf((int)schedule_9_day));
				dutyScoreSummary.setSchedule_10_score(String.valueOf((int)schedule_10_score));
				dutyScoreSummary.setSchedule_10_day(String.valueOf((int)schedule_10_day));
				dutyScoreSummary.setSchedule_11_score(String.valueOf((int)schedule_11_score));
				dutyScoreSummary.setSchedule_11_day(String.valueOf((int)schedule_11_day));
				dutyScoreSummary.setSchedule_12_score(String.valueOf((int)schedule_12_score));
				dutyScoreSummary.setSchedule_12_day(String.valueOf((int)schedule_12_day));
				dutyScoreSummary.setSchedule_13_score(String.valueOf((int)schedule_13_score));
				dutyScoreSummary.setSchedule_13_day(String.valueOf((int)schedule_13_day));
				dutyScoreSummary.setSchedule_14_score(String.valueOf((int)schedule_14_score));
				dutyScoreSummary.setSchedule_14_day(String.valueOf((int)schedule_14_day));
				dutyScoreSummary.setSchedule_15_score(String.valueOf((int)schedule_15_score));
				dutyScoreSummary.setSchedule_15_day(String.valueOf((int)schedule_15_day));
				dutyScoreSummary.setSchedule_16_score(String.valueOf((int)schedule_16_score));
				dutyScoreSummary.setSchedule_16_day(String.valueOf(0));
				
				dutyScoreSummary.setAll_score(String.valueOf((int)all_score));
				dutyScoreSummary.setOvertime_score(String.valueOf((int)overtime_score));
				dutyScoreSummary.setOvertime_pay(String.valueOf((int)overtime_pay));
				dutyScoreSummary.setCreate_id(user_id);
				dutyScoreSummary.setCreate_time(nowDate);
				dutyScoreSummary.setMidnight_score(String.valueOf((int)midnight_score));

				allDutyScoreList.add(dutyScoreSummary);
			}
			
			// 加班费的计算，
			// 加值班费为：加班分值 X 月加班每分值补贴标准
			// 月加班每分值补贴标准=全体在岗民警总数X 710元 ÷全体民警月加班总分
			
			// 月加班每分值补贴标准=全体在岗民警总数X 710元 ÷全体民警月加班总分
			month_per_score = (allMemberCount * 710) / all_mem_overtime_score;
			
			// 设置每个民警考勤的加班费用
			for(DutyScoreSummary oneSummary : allDutyScoreList) {
				// 加值班费为：加班分值 X 月加班每分值补贴标准
				double overtime_pay = Double.parseDouble(oneSummary.getOvertime_score()) * month_per_score;
				oneSummary.setOvertime_pay(String.valueOf((int)overtime_pay));
				
				// 计算得出一个员工本月的计算分数，插入bz_duty_score_summary表,一个员工一个月份只有一条考勤汇总记录
				this.dutyScoreSummaryDao.addDutyScoreSummary(oneSummary);
			}
			
			repMessage.setResponse_code("0");
			repMessage.setResponse_desc("生成考勤成功");
		} catch (Exception e) {
			repMessage.setResponse_code("-1");
			repMessage.setResponse_desc("生成考勤失败");
			repMessage.setResponse_detail(e.getLocalizedMessage());
			logger.warn("生成考勤失败");
		}
		return repMessage;
	}


	@Override
	public RepMessage getDutyAllowanceById(long id) {
		// 查看某个员工某个月份的加值班补贴详细信息，bz_duty_score_summary（staff_id，month）
		RepMessage repMessage = new RepMessage();
		try {
			Map<String, Object> content = new HashMap();

			DutyScoreSummary oneScoreSum = this.dutyScoreSummaryDao.getDutyScoreSummaryById(id);
			if (oneScoreSum != null) {
				String tempStr = oneScoreSum.getMonth() + "";
				String monthStr = tempStr.substring(0, 4) + "年" + tempStr.substring(4) + "月";
				oneScoreSum.setMonthStr(monthStr);
			}
			content.put("result", oneScoreSum);
			repMessage.setContent(content);
			repMessage.setResponse_code("0");
		} catch (Exception e) {
			repMessage.setResponse_code("-1");
			repMessage.setResponse_desc("获取工作量详情失败");
			repMessage.setResponse_detail(e.getLocalizedMessage());
			logger.warn("获取工作量详情失败");
		}
		return repMessage;
	}

	@Override
	public RepMessage queryDutyAllowance(long dept_id, String monthStr, String searchStr, int pageNum, int pageSize) {
		// 加值班补贴统计列表展示（分页）bz_duty_score_summary（dept_id，month，searchStr）
		RepMessage repMessage = new RepMessage();
		try {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
			SimpleDateFormat df2 = new SimpleDateFormat("yyyyMM");
			Date monthDate = df.parse(monthStr);
			String yearMonthStr = df2.format(monthDate);

			long yearMonth = Long.parseLong(yearMonthStr);

			Map<String, Object> map = new HashMap();
			map.put("result",
					this.dutyScoreSummaryDao.queryDutyScoreSummaryByPage(dept_id, yearMonth, searchStr, pageNum, pageSize));
			repMessage.setContent(map);
			repMessage.setResponse_code("0");
		} catch (Exception e) {
			repMessage.setResponse_code("-1");
			repMessage.setResponse_desc("条件查询日志失败");
			repMessage.setResponse_detail(e.getLocalizedMessage());
			logger.warn("条件查询日志失败");
		}
		return repMessage;
	}

}
